package com.jprocms.module.cms.config;

import com.jprocms.module.cms.CmsServerApplication;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWarDeployment;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author jprocms
 */
@ConditionalOnWarDeployment
@Component
@Slf4j
public class WarServletInitializer extends SpringBootServletInitializer implements ApplicationListener<ApplicationReadyEvent>, ApplicationEventPublisher {

    @Value("${server.port}")
    private Integer serverPort;
    @Autowired
    private AbstractAutoServiceRegistration registration;

    @Override
    protected SpringApplicationBuilder configure(
            SpringApplicationBuilder builder) {
        return builder.sources(CmsServerApplication.class);
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        try {
            Field portField = AbstractAutoServiceRegistration.class.getDeclaredField("port");
            portField.setAccessible(true);
            portField.set(registration, new AtomicInteger(serverPort));
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        registration.start();
        log.info("service registration start");
    }

    @Override
    public void publishEvent(ApplicationEvent event) {
        ApplicationEventPublisher.super.publishEvent(event);
    }

    @Override
    public void publishEvent(Object event) {

    }

}